using System;
using System.Collections.Generic;
using System.Text;
using System.Timers;
using System.Threading;
using SpoonCore2.Client;
using SpoonCore2.Tools;

namespace SpoonCore2.Simulation
{
	public class SimulationManager
	{
		//BUG check don't block all threads
		private const int Interval = 10;
		private const int CheckWait = 0;
		private readonly System.Timers.Timer _checkTimer = new System.Timers.Timer(Interval * 1000);
		private ISimulation _runningSimulation;
		private readonly Queue<ISimulation> _simQueue = new Queue<ISimulation>();

		public SimulationManager()
		{
			_checkTimer.Elapsed += CheckTimerElapsed;
			_checkTimer.Start();

			Init();
			Start();
		}

		private void Start()
		{
			while (_simQueue.Count > 0)
			{
				ISimulation item = _simQueue.Dequeue();
				ColorConsole.WriteLine("Start: " + item);
				_runningSimulation = item;
				item.Run();
			}
		}

		private void CheckTimerElapsed(object sender, ElapsedEventArgs e)
		{
			if (_runningSimulation != null)
			{
				//ColorConsole.WriteLine("Pause");
				_runningSimulation.Pause();
				Thread.Sleep(CheckWait * 1000);

				Report(_runningSimulation);

				//ColorConsole.WriteLine("Resume");
				_runningSimulation.Resume();
			}
		}

		private static void Report(ISimulation simulation)
		{
			List<ClientInfo> clients = new List<ClientInfo>();
			foreach (SpoonClient info in simulation.Clients)
			{
				clients.Add(info.Network.ClientInfo);
			}

			ColorConsole.WriteLine();
			ColorConsole.WriteLine("Report (" + DateTime.Now + ")");
			ColorConsole.WriteLine("-----------------------------------");

			bool status = true;
			foreach (SpoonClient client in simulation.Clients)
			{
				if (!client.Network.Check(clients)) status = false;
			}

			string text = "Total: " + status;
			if (status) ColorConsole.WriteLine(text, ConsoleColor.Green);
			else ColorConsole.WriteLine(text, ConsoleColor.Red);

			ColorConsole.WriteLine();
		}

		public void AddSimulation(ISimulation simulation)
		{
			_simQueue.Enqueue(simulation);
		}

		private void Init()
		{
			AddSimulation(new StartSimulation());
			//AddSimulation(new RealSimulation());
		}
	}
}